package xyz.xiaoshengfu.xrpc.data;

import xyz.xiaoshengfu.xrpc.consumer.XRpcConsumerInvokeClient;
import xyz.xiaoshengfu.xrpc.exception.XRpcException;

/**
 * <p>Title: XRpcResult</p>
 * <p>Description: 远程服务执行结果类</p>
 * @author xiaoshengfu(2439323118@qq.com)
 * @date 2020年3月24日
 */
public class XRpcResult {

	public static final int INIT = 0;
	public static final int OK = 1;
	public static final int TIMEOUT = 2;
	public static final int EXCEPTION = 3;
	public static final int ERROR = 4;
	public static final int NO_SERVICE_PROVIDER = 5;

	private String serviceApplicationName;
	private Long requestID;
	private int statusCode = 0;
	private String interfaceName;
	private Integer timeoutTime;
	private Object returnValue;
	private Exception exception;

	public XRpcResult() {
		super();
	}

	public XRpcResult(String interfaceName, Integer timeoutTime) {
		super();
		this.interfaceName = interfaceName;
		this.timeoutTime = timeoutTime;
	}

	public XRpcResult(int statusCode, String interfaceName, Integer timeoutTime) {
		super();
		this.statusCode = statusCode;
		this.interfaceName = interfaceName;
		this.timeoutTime = timeoutTime;
	}

	public String getServiceApplicationName() {
		return serviceApplicationName;
	}

	public void setServiceApplicationName(String serviceApplicationName) {
		this.serviceApplicationName = serviceApplicationName;
	}

	public Long getRequestID() {
		return requestID;
	}

	public void setRequestID(Long requestID) {
		this.requestID = requestID;
	}

	public int getStatusCode() {
		return statusCode;
	}

	public void setStatusCode(int statusCode) {
		this.statusCode = statusCode;
	}

	public String getInterfaceName() {
		return interfaceName;
	}

	public void setInterfaceName(String interfaceName) {
		this.interfaceName = interfaceName;
	}

	public Integer getTimeoutTime() {
		return timeoutTime;
	}

	public void setTimeoutTime(Integer timeoutTime) {
		this.timeoutTime = timeoutTime;
	}

	public Exception getException() {
		return exception;
	}

	public void setException(Exception exception) {
		this.exception = exception;
	}

	public Object getReturnValue() throws Exception {
		synchronized (this) {
			if (statusCode == NO_SERVICE_PROVIDER) {
				throw new XRpcException(serviceApplicationName, interfaceName, XRpcException.NO_SERVICE_PROVIDER);
			} else if (statusCode == INIT) {
				try {
					wait(timeoutTime);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			if (statusCode == OK) {
				return returnValue;
			} else if (statusCode == EXCEPTION) {
				if (exception != null) {
					throw exception;
				} else {
					throw new XRpcException(serviceApplicationName, interfaceName, XRpcException.EXCEPTION);
				}
			} else if (statusCode == ERROR) {
				throw new XRpcException(serviceApplicationName, interfaceName, XRpcException.ERROR);
			} else if (statusCode == INIT) {
				statusCode = TIMEOUT;
				if (serviceApplicationName != null && requestID != null) {
					XRpcConsumerInvokeClient.removeTimeOutXRpcResult(serviceApplicationName, requestID);
				}
				throw new XRpcException(serviceApplicationName, interfaceName, XRpcException.TIMEOUT);
			}
			return null;
		}
	}

	public void setReturnValue(Object returnValue) {
		this.returnValue = returnValue;
	}

}
